package com.kaifamiao.service.impl;

import com.kaifamiao.service.TokenService;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

@Service
public class TokenServiceImpl implements TokenService {

    @Value("${token.secret.key}")
    private String secret;

    private JWSHeader header;
    private JWSSigner signer; // 签名器
    private JWSVerifier verifier; // 验证器

    // init-method
    @PostConstruct
    public void init() {
        header = new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).build();
        try {
            signer = new MACSigner(secret);
            verifier = new MACVerifier(secret);
        } catch ( JOSEException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String generate( String content ) {
        Payload payload = new Payload( content );
        return this.generate(payload);
    }

    // 根据 Payload 创建 JSON Web Token
    private String generate( Payload payload ) {
        JWSObject jwsObject = new JWSObject( header, payload );
        try {
            jwsObject.sign( signer );
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return jwsObject.serialize();
    }

    @Override
    public String generate( Map<String, Object> map ) {
        Payload payload = new Payload( map );
        return this.generate(payload);
    }

    // 将 Json Web Token 解析为 JWSObject实例
    private JWSObject parse( String token ) {
        JWSObject jwsObject = null;
        try {
            jwsObject = JWSObject.parse(token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jwsObject;
    }

    @Override
    public boolean verify( String token ){
        JWSObject jwsObject = this.parse(token);
        try {
            return jwsObject.verify( verifier );
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String toString( String token ) {
        JWSObject jwsObject = this.parse( token );
        return jwsObject.getPayload().toString();
    }

    @Override
    public Map<String,Object> toMap( String token ) {
        JWSObject jwsObject = this.parse(token);
        return jwsObject.getPayload().toJSONObject();
    }

}
